﻿namespace Jsl.FxCop
{
    using System.Linq;
    using System.Collections.Generic;
    using Microsoft.FxCop.Sdk;

    public class VariableUsage
    {
        private TypeNode weakestClassUsed;
        private IEnumerable<InterfaceNode> weakestInterfacesUsed = new InterfaceNode[] { };

        #region Constrcutors
        /// <summary>
        /// Initializes a new instance of the <see cref="VariableUsage"/> class.
        /// </summary>
        public VariableUsage()
        {
        }
        #endregion Constrcutors

        #region Public Properties
        /// <summary>
        /// Gets the weakest class used.
        /// </summary>
        /// <value>The weakest class used.</value>
        public TypeNode WeakestClassUsed
        {
            get { return this.weakestClassUsed; }
        }

        /// <summary>
        /// Gets the weakest interfaces used.
        /// </summary>
        /// <value>The weakest interfaces used.</value>
        public IEnumerable<InterfaceNode> WeakestInterfacesUsed
        {
            get { return this.weakestInterfacesUsed; }
        }
        #endregion Public Properties

        #region Public Methods
        /// <summary>
        /// Adds the variable usage.
        /// </summary>
        /// <param name="assignedType">Type that is being assigned to the variable.</param>
        public void AddUsage(TypeNode assignedType)
        {
            var interfaceNode = assignedType as InterfaceNode;
            if (interfaceNode == null)
            {
                this.AddClassOrStructUsage(assignedType);
            }
            else
            {
                this.AddInterfaceUsage(interfaceNode);
            }
        }
        #endregion Public Methods

        #region Private Methods
        private void AddClassOrStructUsage(TypeNode typeUsed)
        {
            if (this.weakestClassUsed == null)
            {
                this.weakestClassUsed = typeUsed;
            }
            else
            {
                this.weakestClassUsed = this.weakestClassUsed.GetCommonClass(typeUsed);
            }
        }

        private void AddInterfaceUsage(InterfaceNode interfaceNode)
        {
            if (!this.weakestInterfacesUsed.Any())
            {
                this.weakestInterfacesUsed = new InterfaceNode[] { interfaceNode };
            }
            else
            {
                this.weakestInterfacesUsed = this.weakestInterfacesUsed.GetCommonInterfaces(interfaceNode);
            }
        }
        #endregion Private Methods
    }
}